<template>
  <div class="Box">
    <div class="child" :class="{ empty: item == EmptyValue }" @click="Move(item)" v-for="(item,i) in BlockValue" :style="{
      width : `${300 / Size}px`,
      height : `${300 / Size}px`,
      transform: `translateX(${item % Size * (300 / Size)}px) translateY(${parseInt(item / Size) * (300 / Size)}px)`
    }">
      <svg x="0px" y="0px" viewBox="0 0 300 300" :style="{
        transform: `translateX(-${i % Size * (300 / Size)}px) translateY(-${parseInt(i / Size) * (300 / Size)}px)`
      }">
        <rect fill="#11A2CE" width="300" height="300" />
        <rect x="17.9" y="10.6" fill="#64CC12" stroke="#231815" stroke-miterlimit="10" width="161.5" height="168.8" />
        <circle cx="200" cy="160" r="80" fill="#CC6517" stroke="#231815" stroke-miterlimit="10" />
        <polygon fill="#E2DA49" stroke="#231815" stroke-miterlimit="10" points="111.4,125.8 204.8,287.6 17.9,287.6 " />
      </svg>
    </div>
  </div>
  <br>
  <div>步数：{{ num }}</div>
  <a-button type="" @click="Init">{{ !isComplete ? '重置' : '重新开始' }}</a-button>
</template>
<script setup>
import { onMounted, ref, watch } from 'vue'

// 尺寸（难度）
const Size = ref(3);
// 步数计数
const num = ref(0);
// 数据源  值 代表 当前数据应该在哪
//        下标代表 应该在哪
const BlockValue = ref([0, 1, 2, 3, 4, 5, 6, 7, 8]);
// 设计一个完成的数据，来决定是否已经完成
let CheckSrting = '0, 1, 2, 3, 4, 5, 6, 7, 8';
// 将最后一个块设定为空，所有移动操作的判断条件
const EmptyValue = ref(8);
// 游戏状态
const isComplete = ref(false);

// 检查 游戏是否结束
const Check = () => {
  isComplete.value = BlockValue.value.join() == CheckSrting;
}

// 移动块位置
const Move = (item) => {
  var From = EmptyValue.value;
  var To = item;
  // 判断  X轴值相等，Y轴相差1 或者 Y轴相等，X轴相差1的 时候可以移动
  if ((From % Size.value == To % Size.value && Math.abs(parseInt(From / Size.value) - parseInt(To / Size.value)) == 1)
    || (Math.abs(From % Size.value - To % Size.value) == 1 && parseInt(From / Size.value) == parseInt(To / Size.value))) {
    // 移动位置，其实就是交换两个块当前所在位置 
    var ToIndex = BlockValue.value.indexOf(item);
    var FromIndex = BlockValue.value.indexOf(EmptyValue.value);
    BlockValue.value[ToIndex] = From;
    BlockValue.value[FromIndex] = To;
    EmptyValue.value = To;
    // 成功移动一次，进行一次计数
    num.value++;
    // 并且检查一下当前游戏是否结束
    Check();
  };
};

// 初始化游戏
const Init = () => {
  num.value = 0;
  // 重置游戏状态
  isComplete.value = false;
  // 计算块总数
  var Length = Size.value * Size.value;
  var Value = [];
  for (let i = 0; i < Length; i++) {
    Value.push(i);
  };
  CheckSrting = Value.join();
  // 随机排列一下数据
  Value.sort(() => {
    return Math.random() > .5 ? -1 : 1;
  });
  BlockValue.value = Value;
  // // 默认最后一个为可移动块
  EmptyValue.value = Value[Length - 1];
}

watch(isComplete, val => {
  val && alert('成功，步数：' + num.value);
})

onMounted(() => {
  // 加载成功时，初始化
  Init();
})

</script>
<style lang="less" scoped>
.Box {
  width: 300px;
  height: 300px;
  position: relative;
  background-color: #333;
}

.child {
  overflow: hidden;
  background-color: #333;
  position: absolute;
  left: 0;
  right: 0;
  transition: all 200ms;
}

.child.empty {
  z-index: -1;
}

.child.empty svg {
  display: none;
}

svg {
  width: 300px;
  height: 300px;
}
</style>
